<?php
namespace Libs;

class Config
{
    public $raw;
    public $data;

    //读取配置文件, 初始化成员变量
    public function __construct($key='', $args=[])
    {
        if (!empty($key)) {
            $cache_file = 'config_cache_'.ENV; 
            $cache_path = CONFIGPATH.$cache_file.'.php'; //当前运行环境的所有配置的缓存文件路径
            $config_path = CONFIGPATH.$key.'.php'; //某个配置文件路径
            
            if (file_exists($cache_path)) {
                if (isset($GLOBALS[$cache_file][$key])) {
                    $this->raw = $this->data = $GLOBALS[$cache_file][$key];
                } else {
                    include($cache_path);
                    $this->raw = $this->data = $GLOBALS[$cache_file][$key] ?? null;
                }

            } elseif (file_exists($config_path)) {
                if (isset($GLOBALS['config'][$key])) {
                    $this->raw = $this->data = $GLOBALS['config'][$key];
                } else {
                    include($config_path);
                    $this->raw = $this->data = $GLOBALS['config'][$key] ?? null;
                } 
                
            } else {
                $this->raw = $this->data = null;
            }
        }
    }

    //直接给成员变量赋值, 不用读取配置变量
    public static function setData($data)
    {
        $obj = new self();
        $obj->raw = $obj->data = $data;
        return $obj;
    }

    //用来返回实例化对象
    public static function __callStatic($name, $args)
    {
        $obj = new self($name, $args);
        if (empty($args)) {
            return $obj;
        } else {
            $arrKey = explode('.', $args[0]);
            $count = count($arrKey);
            $data = $obj->data;
            for ($i=0; $i<$count; $i++) {
                $k = $arrKey[$i];
                $data = isset($data[$k]) ? $data[$k] : '';
            }
            return $data;
        }
    }

    //获取不存在的成员变量, 并更新成员变量$data
    public function __get($key)
    {
        if (isset($this->data[$key])) {
            $tmp = $this->data[$key];
            if (is_scalar($tmp) || is_null($tmp)) {
                return $tmp;
            } else {
                $this->data = $tmp; //覆盖当前值
                return $this; //便于链式调用
            }
        } else {
            return null;
        }
    }

    public function __toString()
    {
        return json_encode($this->data);
    }

    //获取配置文件所有变量, 也防止变量中有键名为`raw`的数据
    public function raw()
    {
        return $this->raw;
    }

    //获取当前值
    public function data()
    {
        return $this->data;
    }

    //获取所有键名
    public function keys()
    {
        return array_keys($this->data);
    }

    //获取所有值
    public function values()
    {
        return array_values($this->data);
    }

    //取出某一列的值
    public function column($field, $index=null)
    {
        return array_column($this->data, $field, $index);
    }
}